package cn.sjtu.security.handler;

import cn.hutool.core.util.StrUtil;
import cn.sjtu.security.utils.GlobalConstants;
import cn.sjtu.security.utils.JwtUtils;
import cn.sjtu.security.vo.HttpResult;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 退出成功处理器
 */
@Component
@Slf4j
public class LogoutSuccessfulHandler implements LogoutSuccessHandler {
    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private JwtUtils jwtUtils;

    @Override
    public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {

        // 1. 从请求头中获取jwt
        String auth = httpServletRequest.getHeader("Authorization");
        if(StrUtil.isBlank(auth)) {
            HttpResult httpResult = HttpResult.builder().code(0).msg("登出失败！").data("").build();
            this.printFront(httpServletRequest, httpServletResponse, httpResult);
            return;
        }

        // 2. 如果auth不为空
        String jwt = auth.replace("bearer ", "");
        if(StrUtil.isBlank(jwt)) {
            HttpResult httpResult = HttpResult.builder().code(0).msg("登出失败！").data("").build();
            this.printFront(httpServletRequest, httpServletResponse, httpResult);
            return;
        }

        // 3. 校验token
        boolean b = jwtUtils.verifyToken(jwt);

        // 4. 如果校验失败
        if(!b) {
            HttpResult httpResult = HttpResult.builder().code(0).msg("登出失败！").data("").build();
            this.printFront(httpServletRequest, httpServletResponse, httpResult);
            return;
        }

        // 5. 入如果校验成功则删除redis中的
        stringRedisTemplate.delete(GlobalConstants.LOGIN_TOKEN_PREFIX + jwt);
        HttpResult httpResult = HttpResult.builder().code(1).msg("登出成功！").data("").build();
        this.printFront(httpServletRequest, httpServletResponse, httpResult);
    }

    /**
     * 传入一个结果对象并返回前端
     * @param httpServletRequest
     * @param httpServletResponse
     * @param httpResult
     * @throws IOException
     */
    public void printFront(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, HttpResult httpResult) throws IOException {
        String s = objectMapper.writeValueAsString(httpResult);
        httpServletResponse.setContentType("application/json;charset=utf-8");
        PrintWriter writer = httpServletResponse.getWriter();
        writer.write(s);
        writer.flush();
    }
}
